package com.aspire.aimini.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.aspire.aimini.model.dto.AiConfigDTO;
import com.aspire.aimini.model.entity.AiConfig;
import com.aspire.aimini.model.vo.Result;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import com.aspire.aimini.service.AiConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

/**
 * AI配置控制器
 *
 * @author wangguiyou
 * @date 2024-12-19
 */
@Slf4j
@RestController
@RequestMapping("/api/ai-config")
@RequiredArgsConstructor
@Tag(name = "AI配置管理", description = "AI配置相关的API接口")
public class AiConfigController {

    private final AiConfigService aiConfigService;

    /**
     * 创建AI配置
     *
     * @return 创建的AI配置
     */
        @PostMapping
    @Operation(summary = "创建AI配置", description = "创建新的AI配置")
    public Result<AiConfig> createAiConfig(
            @Valid @RequestBody AiConfigDTO aiConfigDTO) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("创建AI配置: userId={}, serviceType={}", userId, aiConfigDTO.getServiceType());

        AiConfig aiConfig = new AiConfig();
        BeanUtils.copyProperties(aiConfigDTO, aiConfig);
        aiConfig.setUserId(userId);
        AiConfig created = aiConfigService.createAiConfig(aiConfig);
        return Result.success(created);
    }

    /**
     * 分页查询AI配置
     *
     * @param serviceType 服务类型
     * @param provider    提供商
     * @param status      状态
     * @param pageable    分页参数
     * @return AI配置分页列表
     */
        @GetMapping
    @Operation(summary = "分页查询AI配置", description = "分页查询AI配置列表")
    public Result<Page<AiConfig>> getAiConfigs(
            @RequestParam(required = false) String serviceType,
            @RequestParam(required = false) String provider,
            @RequestParam(required = false) String status,
            Pageable pageable) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("分页查询AI配置: userId={}, serviceType={}, provider={}, status={}",
                userId, serviceType, provider, status);

        Page<AiConfig> configs = aiConfigService.getAiConfigs(userId, serviceType, provider, status, pageable);
        return Result.success(configs);
    }

    /**
     * 根据ID获取AI配置
     *
     * @param id     配置ID
     * @return AI配置信息
     */
        @GetMapping("/{id}")
    @Operation(summary = "根据ID获取AI配置", description = "根据ID获取AI配置详情")
    public Result<AiConfig> getAiConfigById(@PathVariable Long id) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("根据ID获取AI配置: id={}, userId={}", id, userId);

        AiConfig config = aiConfigService.getAiConfigById(id);
        return Result.success(config);
    }

    /**
     * 根据用户ID获取AI配置
     *
     * @return AI配置列表
     */
        @GetMapping("/user")
    @Operation(summary = "根据用户ID获取AI配置", description = "获取用户的所有AI配置")
    public Result<List<AiConfig>> getAiConfigsByUserId() {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("根据用户ID获取AI配置: userId={}", userId);

        List<AiConfig> configs = aiConfigService.getAiConfigsByUserId(userId);
        return Result.success(configs);
    }

    /**
     * 根据服务类型获取AI配置
     *
     * @param serviceType 服务类型
     * @param userId      用户ID
     * @return AI配置列表
     */
        @GetMapping("/service-type/{serviceType}")
    @Operation(summary = "根据服务类型获取AI配置", description = "根据服务类型获取AI配置")
    public Result<List<AiConfig>> getAiConfigsByServiceType(@PathVariable String serviceType) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("根据服务类型获取AI配置: serviceType={}, userId={}", serviceType, userId);

        List<AiConfig> configs = aiConfigService.getAiConfigsByServiceType(serviceType, userId);
        return Result.success(configs);
    }

    /**
     * 获取默认AI配置
     *
     * @param serviceType 服务类型
     * @param userId      用户ID
     * @return 默认AI配置
     */
        @GetMapping("/default/{serviceType}")
    @Operation(summary = "获取默认AI配置", description = "获取指定服务类型的默认AI配置")
    public Result<AiConfig> getDefaultAiConfig(@PathVariable String serviceType) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("获取默认AI配置: serviceType={}, userId={}", serviceType, userId);

        AiConfig config = aiConfigService.getDefaultAiConfig(serviceType, userId);
        return Result.success(config);
    }

    /**
     * 获取系统默认AI配置
     *
     * @param serviceType 服务类型
     * @return 系统默认AI配置
     */
    @GetMapping("/system-default/{serviceType}")
    @Operation(summary = "获取系统默认AI配置", description = "获取指定服务类型的系统默认AI配置")
    public Result<AiConfig> getSystemDefaultAiConfig(
            @Parameter(description = "服务类型") @PathVariable String serviceType) {
        log.info("获取系统默认AI配置: serviceType={}", serviceType);

        AiConfig config = aiConfigService.getSystemDefaultAiConfig(serviceType);
        return Result.success(config);
    }

    /**
     * 更新AI配置
     *
     * @param id       配置ID
     * @param aiConfig 更新的AI配置信息
     * @param userId   用户ID
     * @return 更新后的AI配置
     */
        @PutMapping("/{id}")
    @Operation(summary = "更新AI配置", description = "更新AI配置信息")
    public Result<AiConfig> updateAiConfig(
            @PathVariable Long id,
            @Valid @RequestBody AiConfigDTO aiConfigDTO) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("更新AI配置: id={}, userId={}", id, userId);

        AiConfig aiConfig = new AiConfig();
        BeanUtils.copyProperties(aiConfigDTO, aiConfig);
        aiConfig.setId(id);
        AiConfig updated = aiConfigService.updateAiConfig(aiConfig);
        return Result.success(updated);
    }

    /**
     * 删除AI配置
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 删除结果
     */
        @DeleteMapping("/{id}")
    @Operation(summary = "删除AI配置", description = "删除指定的AI配置")
    public Result<Void> deleteAiConfig(@PathVariable Long id) {
                Long userId = StpUtil.getLoginIdAsLong();
        log.info("删除AI配置: id={}, userId={}", id, userId);

        aiConfigService.deleteAiConfig(id);

        return Result.success();
    }

    /**
     * 批量删除AI配置
     *
     * @param ids    配置ID列表
     * @param userId 用户ID
     * @return 删除结果
     */
        @DeleteMapping("/batch")
    @Operation(summary = "批量删除AI配置", description = "批量删除AI配置")
    public Result<Void> batchDeleteAiConfigs(@RequestBody List<Long> ids) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("批量删除AI配置: ids={}, userId={}", ids, userId);

        aiConfigService.batchDeleteAiConfigs(ids);
        return Result.success();
    }

    /**
     * 设置默认AI配置
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 设置结果
     */
        @PostMapping("/{id}/set-default")
    @Operation(summary = "设置默认AI配置", description = "将指定配置设置为默认配置")
    public Result<Void> setDefaultAiConfig(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("设置默认AI配置: id={}, userId={}", id, userId);

        aiConfigService.setDefaultAiConfig(id, userId);
        return Result.success();
    }

    /**
     * 测试AI配置连接
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 测试结果
     */
        @PostMapping("/{id}/test-connection")
    @Operation(summary = "测试AI配置连接", description = "测试AI配置的连接状态")
    public Result<Boolean> testConnection(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("测试AI配置连接: id={}, userId={}", id, userId);

        boolean success = aiConfigService.testConnection(id);
        return Result.success(success);
    }

    /**
     * 增加今日使用量
     *
     * @param id      配置ID
     * @param request 使用量信息
     * @param userId  用户ID
     * @return 更新结果
     */
        @PostMapping("/{id}/increment-usage")
    @Operation(summary = "增加今日使用量", description = "增加AI配置的今日使用量")
    public Result<Void> incrementTodayUsage(
            @PathVariable Long id,
            @Valid @RequestBody Map<String, Object> request) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("增加今日使用量: id={}, userId={}", id, userId);

        Integer amount = (Integer) request.get("amount");
        aiConfigService.incrementTodayUsage(id, amount);
        return Result.success();
    }

    /**
     * 重置今日使用量
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 重置结果
     */
        @PostMapping("/{id}/reset-usage")
    @Operation(summary = "重置今日使用量", description = "重置AI配置的今日使用量")
    public Result<Void> resetTodayUsage(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("重置今日使用量: id={}, userId={}", id, userId);

        aiConfigService.resetTodayUsage(id);
        return Result.success();
    }

    /**
     * 检查配置可用性
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 可用性状态
     */
        @GetMapping("/{id}/availability")
    @Operation(summary = "检查配置可用性", description = "检查AI配置的可用性")
    public Result<Boolean> checkAvailability(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("检查配置可用性: id={}, userId={}", id, userId);

        boolean available = aiConfigService.checkAvailability(id);
        return Result.success(available);
    }

    /**
     * 根据提供商获取配置
     *
     * @param provider 提供商
     * @param userId   用户ID
     * @return AI配置列表
     */
        @GetMapping("/provider/{provider}")
    @Operation(summary = "根据提供商获取配置", description = "根据提供商获取AI配置")
    public Result<List<AiConfig>> getAiConfigsByProvider(@PathVariable String provider) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("根据提供商获取配置: provider={}, userId={}", provider, userId);

        List<AiConfig> configs = aiConfigService.getAiConfigsByProvider(provider, userId);
        return Result.success(configs);
    }

    /**
     * 按服务类型统计配置数量
     *
     * @param userId 用户ID
     * @return 统计结果
     */
        @GetMapping("/statistics/by-service-type")
    @Operation(summary = "按服务类型统计配置数量", description = "按服务类型统计AI配置数量")
    public Result<Map<String, Long>> countByServiceType() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("按服务类型统计配置数量: userId={}", userId);

        Map<String, Long> statistics = aiConfigService.countByServiceType(userId);
        return Result.success(statistics);
    }

    /**
     * 按提供商统计配置数量
     *
     * @param userId 用户ID
     * @return 统计结果
     */
        @GetMapping("/statistics/by-provider")
    @Operation(summary = "按提供商统计配置数量", description = "按提供商统计AI配置数量")
    public Result<Map<String, Long>> countByProvider() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("按提供商统计配置数量: userId={}", userId);

        Map<String, Long> statistics = aiConfigService.countByProvider(userId);
        return Result.success(statistics);
    }

    /**
     * 获取即将超出配额的配置
     *
     * @param threshold 阈值百分比
     * @param userId    用户ID
     * @return 配置列表
     */
        @GetMapping("/quota/near-limit")
    @Operation(summary = "获取即将超出配额的配置", description = "获取即将超出配额的AI配置")
    public Result<List<AiConfig>> getConfigsNearQuotaLimit(
            @RequestParam(defaultValue = "80") Integer threshold) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("获取即将超出配额的配置: threshold={}, userId={}", threshold, userId);

        List<AiConfig> configs = aiConfigService.getConfigsNearQuotaLimit(threshold, userId);
        return Result.success(configs);
    }

    /**
     * 获取已超出配额的配置
     *
     * @param userId 用户ID
     * @return 配置列表
     */
        @GetMapping("/quota/exceeded")
    @Operation(summary = "获取已超出配额的配置", description = "获取已超出配额的AI配置")
    public Result<List<AiConfig>> getConfigsExceededQuota() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("获取已超出配额的配置: userId={}", userId);

        List<AiConfig> configs = aiConfigService.getConfigsExceededQuota(userId);
        return Result.success(configs);
    }

    /**
     * 获取用户配置统计信息
     *
     * @param userId 用户ID
     * @return 统计信息
     */
        @GetMapping("/statistics/user")
    @Operation(summary = "获取用户配置统计信息", description = "获取用户的AI配置统计信息")
    public Result<Map<String, Object>> getUserConfigStatistics() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("获取用户配置统计信息: userId={}", userId);

        Map<String, Object> statistics = aiConfigService.getUserConfigStatistics(userId);
        return Result.success(statistics);
    }

    /**
     * 复制AI配置
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 复制的配置
     */
        @PostMapping("/{id}/copy")
    @Operation(summary = "复制AI配置", description = "复制指定的AI配置")
    public Result<AiConfig> copyAiConfig(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("复制AI配置: id={}, userId={}", id, userId);

        AiConfig copied = aiConfigService.copyAiConfig(id, userId);
        return Result.success(copied);
    }

    /**
     * 启用AI配置
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 操作结果
     */
        @PostMapping("/{id}/enable")
    @Operation(summary = "启用AI配置", description = "启用指定的AI配置")
    public Result<Void> enableAiConfig(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("启用AI配置: id={}, userId={}", id, userId);

        aiConfigService.enableAiConfig(id);
        return Result.success();
    }

    /**
     * 禁用AI配置
     *
     * @param id     配置ID
     * @param userId 用户ID
     * @return 操作结果
     */
        @PostMapping("/{id}/disable")
    @Operation(summary = "禁用AI配置", description = "禁用指定的AI配置")
    public Result<Void> disableAiConfig(@PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("禁用AI配置: id={}, userId={}", id, userId);

        aiConfigService.disableAiConfig(id);
        return Result.success();
    }

    /**
     * 批量更新配置状态
     *
     * @param request 批量更新请求
     * @param userId  用户ID
     * @return 更新结果
     */
        @PostMapping("/batch/update-status")
    @Operation(summary = "批量更新配置状态", description = "批量更新AI配置状态")
    public Result<Void> batchUpdateStatus(
            @Valid @RequestBody Map<String, Object> request) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("批量更新配置状态: userId={}", userId);

        @SuppressWarnings("unchecked")
        List<Long> ids = (List<Long>) request.get("ids");
        String status = (String) request.get("status");

        aiConfigService.batchUpdateStatus(ids, status);
        return Result.success();
    }

    /**
     * 导入AI配置
     *
     * @param file   配置文件
     * @param userId 用户ID
     * @return 导入结果
     */
        @PostMapping("/import")
    @Operation(summary = "导入AI配置", description = "从文件导入AI配置")
    public Result<Integer> importAiConfigs(
            @RequestParam("file") MultipartFile file) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("导入AI配置: userId={}, fileName={}", userId, file.getOriginalFilename());

        List<AiConfig> imported = aiConfigService.importAiConfigs(file, userId);
        return Result.success(imported.size());
    }

    /**
     * 导出AI配置
     *
     * @param userId 用户ID
     * @param format 导出格式
     * @return 导出文件
     */
        @GetMapping("/export")
    @Operation(summary = "导出AI配置", description = "导出用户的AI配置")
    public ResponseEntity<byte[]> exportAiConfigs(
            @RequestParam(defaultValue = "json") String format) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("导出AI配置: userId={}, format={}", userId, format);

        byte[] data = aiConfigService.exportAiConfigs(userId, format);

        return ResponseEntity.ok()
                .header("Content-Disposition", "attachment; filename=ai-configs." + format)
                .header("Content-Type", "application/octet-stream")
                .body(data);
    }

    /**
     * 删除用户所有配置
     *
     * @param userId 用户ID
     * @return 删除结果
     */
        @DeleteMapping("/user/all")
    @Operation(summary = "删除用户所有配置", description = "删除用户的所有AI配置")
    public Result<Void> deleteAllUserConfigs() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("删除用户所有配置: userId={}", userId);

        aiConfigService.deleteAllUserConfigs(userId);
        return Result.success();
    }
}